package me.zhengjie.tool;


import com.alibaba.fastjson2.JSONObject;

import java.util.Calendar;
import java.util.Date;


public class AnalyticalSnowflakeId {

    private static long twepoch = 1288834974657L;

    private long workerIdBits = 5L;
    private long datacenterIdBits = 5L;

//    private static final long sequenceBits = 12L;
    private static final long SEQUENCEBITS = 12L;

    private long workerIdShift = SEQUENCEBITS;
    private long dataCenterIdShift = SEQUENCEBITS + workerIdBits;
    private long timestampLeftShift = SEQUENCEBITS + workerIdBits + datacenterIdBits;

    static {
        Calendar calendar = Calendar.getInstance();
        calendar.set(2016, Calendar.NOVEMBER, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        twepoch = calendar.getTimeInMillis();
    }

    public JSONObject parseInfo(long id) {
        String sonwFlakeId = Long.toBinaryString(id);
        int len = sonwFlakeId.length();
        JSONObject jsonObject = new JSONObject();
        int sequenceStart = (int) (len < workerIdShift ? 0 : len - workerIdShift);
        int workerStart = (int) (len < dataCenterIdShift ? 0 : len - dataCenterIdShift);
        int timeStart = (int) (len < timestampLeftShift ? 0 : len - timestampLeftShift);
        String sequence = sonwFlakeId.substring(sequenceStart, len);
        String workerId = sequenceStart == 0 ? "0" : sonwFlakeId.substring(workerStart, sequenceStart);
        String dataCenterId = workerStart == 0 ? "0" : sonwFlakeId.substring(timeStart, workerStart);
        String time = timeStart == 0 ? "0" : sonwFlakeId.substring(0, timeStart);
        int sequenceInt = Integer.valueOf(sequence, 2);
        jsonObject.put("sequence", sequenceInt);
        int workerIdInt = Integer.valueOf(workerId, 2);
        jsonObject.put("workerId", workerIdInt);
        int dataCenterIdInt = Integer.valueOf(dataCenterId, 2);
        jsonObject.put("dataCenter", dataCenterIdInt);
        long diffTime = Long.parseLong(time, 2);
        long timeLong = diffTime + twepoch;
        Date date = fromatTime(timeLong);
        jsonObject.put("date", date);
        return jsonObject;
    }

    public static Date getSonwFlakeDate(long id) {
        AnalyticalSnowflakeId sonwFlakeId = new AnalyticalSnowflakeId();
        JSONObject jsonObject = sonwFlakeId.parseInfo(id);
        Object dateObj = jsonObject.get("date");
        return (Date) dateObj;
    }

    private static Date fromatTime(long date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(date);
        return calendar.getTime();
    }

//    public static void main(String[] args) {
//        AnalyticalSnowflakeId sonwFlakeId = new AnalyticalSnowflakeId();
//        System.out.println(DateUtil.getCurDateTime());
//        int j = 0;
//        long id = 0L;
//        String lastId = "";
//        IdGenerator generator = IdGenerator.instance;
//        for (int i = 0; i< 10; i++) {
//            j = j + 1;
//            lastId = generator.nextStringId();
//            id = generator.nextNumberId().longValue();
//            System.out.println(id);
//            sonwFlakeId = new AnalyticalSnowflakeId();
//            JSONObject jsonObject = sonwFlakeId.parseInfo(id);
//            System.out.println(jsonObject);
//            Object dateObj = jsonObject.get("date");
//            System.out.println("date:" + dateObj);
//            System.out.println("------------------------------------------");
//        }
//        System.out.println(DateUtil.getCurDateTime());
//        System.out.println(lastId);
//        System.out.println(j);
//    }

}
